﻿using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;


//UniTask 官方说明 （ 之前只是没讲到 所以没说 尽量遵守）
//1.关于async void 与async UniTaskVoid 
//2.考虑性能的话 请使用 UniTask.SuppressCancellationThrow  返回值(不抛出异常,无需处理异常,而是通过返回值来表示) (bool IsCanceled, T Result)
//3.超时处理本质上是取消   Unity中建议使用CancellationTokenSouce.CancelAfterSlim(TimeSpan)
//CancellationTokenSouce.CancelAfter是c#提供的原生api 在Unity中不该使用 
// 异步等待资源加载完成 Task.WithCancellation(token);

//Forget 方法 UniTask提供 同步方法中调用异步方法 不想await 又不想有警告 可用Forget (消除 async await 传染性)
public class Ten : MonoBehaviour
{
    public Button btn1;
    public Button btn2;
    public Text text1;
    public Text text2;
    public string url1 = "https://www.baidu.com/";
    public string url2 = "https://www.google.com/";

    private void Start()
    {
        btn1.onClick.AddListener(() =>
        {
            OnClickTest(url1, text1).Forget();
        });

        btn2.onClick.AddListener(() =>
        {
            _ = OnClickTest(url2, text2);
        });
    }

    public async UniTask<string> VisitWeb(string url, float timeout)
    {
        var cts = new CancellationTokenSource();

        //在指定时间后取消任务
        cts.CancelAfterSlim(TimeSpan.FromSeconds(timeout));
        //没有抛出异常 通过返回值判断任务是否取消
        //返回值 bool T
        //SuppressCancellationThrow 抛出异常的第二种方式
        //发送网络请求 并且会有一个取消异常 
        // 返回值 第一个参数 bool 是否取消 第二个参数结果
        var (failed, result) = await UnityWebRequest.Get(url).SendWebRequest().WithCancellation(cts.Token).SuppressCancellationThrow();

        if (!failed) return result.downloadHandler.text.Substring(0, 20);

        //如果等到指定时间任务取消了 说明等待时间内都没连上
        return "超时";
    }

    private async UniTaskVoid OnClickTest(string url, Text text)
    {
        var res = await VisitWeb(url, 2);

        text.text = res;
    }
}